#pragma once
#include<iostream>
#include <string>
#include "log.hpp"
#include "Thread.hpp"
#include <vector>
#include <queue>
#include "mutex.hpp"
#include "Conddex.hpp"
namespace Threadpoolmodule
{
    const int gnums = 5;
    using namespace logmodule;
    using namespace ThreadModule;
    using namespace ConddexModule;
    using namespace MutexModule;
    template<typename T>
    class ThreadPool
    {
        private:
        //唤醒所有的线程
        void wakeupallthread()
        {
            _cond.broadcast();//使用这个操作唤醒所有的线程 
            LOG(level::INFO)<<"唤醒了所有的线程";
        }
        public:
        ThreadPool(int num = gnums)://创建若干个线程对象
        _nums(num)
        ,_isrunning(false)
        {
            for(int i = 0;i<num;i++)
            {
                _threads.emplace_back([this]()
            {
                handertask();
            })
            }
        }
        void start()
        {
            if(_isrunning)
            return ;
            _isrunning = true;
            for(auto &thread :_threads)
            {
                thread.start();
            }
        }

        void stop()
        {
            if(!_isrunning)
            return ;
            _isrunning = false;
        }

        void hadertask()
        {
            char name[128];
            pthread_get_name_np(pthread_self(),name,sizeof(name));
            while(true)
            {
                T t;
                {
                lockguard guarder(_mutex);
                //线程醒来所需要检查的条件（线程没退，任务队列是空的）
                while(_taskkq.empty()&&_isrunning==true)
                {
                    _cond.wait(_mutex);//没有任务就会一直休眠
                }
                //线程被唤醒，正常处理任务
                if(!_isrunning&&_taskkq.empty())
                {
                    LOG(level::INFO)<<name<<"任务队列为空，运行状态为假，线程执行退出操作"；
                    break;
                }
                t = _taskkq.front();
                _taskkq,pop();
                }
                t();
            }
        }
        ~ThreadPool()
        {}
        private:
        std::vector<Thread> _threads;
        int _nums;//线程池中具体现成的个数
        std::queue<T> _taskkq;
        Conddex _cond;
        Mutex _mutex;

        bool _isrunning;//方便对线程池进行停止
    };
}